プログラマー脳 ~優れたプログラマーになるための認知科学に基づくアプローチ
https://gyazo.com/84d39e78c0afa629e823daf80f91d548
オランダ人、オランダのライデン大学准教授、プログラミング教育やプログラミング言語について研究している
原題: The Programmer's Brain: What every programmer needs to know about cognition
変に意訳せずに率直に訳したタイトルで好感持てる
原著は2021年発売
目次
・第1章:プログラミングを行う際に重要な3つの認知プロセスと、それぞれの認知プロセスがどのような混乱と関連するか ・第2章:コードを素早く読み、その仕組みを理解する方法
・第3章:プログラミングの構文や概念をよりよく、より簡単にきちんと学ぶ方法
・第4章:複雑なコードを読み解くためのテクニック
・第5章:見慣れないコードをしっかりと理解するためのテクニック
・第6章:プログラミングにおける問題解決のテクニック
・第7章:コードや思考中のバグを回避するためのテクニック
・第8章:特にコードベース全体において、明確な変数名を選択する方法
・第9章:「コードの臭い」とその背後にある認知科学的背景
・第10章:複雑な問題を解決するための、より高度なテクニック
・第11章:コーディングという行為そのものと、プログラミングにおけるさまざまなタスク
・第12章:大規模なコードベースを改善する方法
・第13章:新しい開発者のオンボーディングプロセスの苦痛を軽減する方法
(このamazonから引用した目次は、実際の本の中の目次とは異なる)
認知科学のアプローチから攻めるという点では似ている。
読んで感銘を受けたkidooom.icon
本書のテクニックを使えば、複雑なコードを読み解きやすくなると思う
Chapter1. コーディング中の混乱を紐解く
コーディング中の混乱には、3つのタイプがある
1. 知識不足
本書で挙げられている APLのコード例は、さっぱり理解できない。知識不足による混乱を生じさせる code:apl
2 2 2 2 2 T n
この混乱は、長期記憶にこのコードを読み解くのに必要な情報が存在しないことを示す 2. 情報不足
Java のコード例では、toBinaryString()関数の内部がどういう処理をしているか分からない混乱を生じさせる
code:java
public class BinaryCalulator {
public static void mian(Integer n){
System.out.println(Integer.toBinaryString(n));
}
}
この混乱は、短期記憶に情報が存在しない、忘れてしまっていることから起きる 3. 処理能力の不足
BASICのコードでは、変数に記録される処理途中の値や処理内容を頭の中に保持するのが難しい混乱が生じる
code:basic
1 LET N2 = ABS ( INT ( N ) )
2 LET B$ = ""
3 FOR N1 = N2 TO 0 STEP 0
4 LET N2 = INT ( N1 / 2 )
5 LET B$ = STR$ (N1-N2*2) + B$
6 LET N1 = N2
7 NEXT N1
8 PRINT B$
9 RETURN
コードを読んでいて混乱をした場合は、まず自分がどの種類の混乱をしているか?を認識することで、対策が考えられる
処理能力の不足の場合は、メモやコメントを追加する、デバッグする、リファクタリングするなど
長期記憶の不足の場合は、まず調査する、本を読んだりググったりChatGPTに確認してみるなど Chapter2. コードを速読する
コードを読む時間は、コードを書く時間よりも圧倒的に長い
抽象度の高いパーツは、長期記憶から呼び出されて認識する
マジックナンバーや特化した処理は、短期記憶やワーキングメモリを使用する
本章で挙げられているヘンテコなサンプルコードは、理解して記憶するのがとても難しい
code:java
void execute(int x[]){
int b = x.length;
for (int v = b / 2 - 1; v >= 0; v--)
func(x, b, v);
for (int l = b-1; l > 0; l--)
// 省略
馴染みのないコードは、脳のキャッシュから呼び出されずに新規情報として扱われるため、読むことが難しい
チェスのプレイヤーの実験例。チャスの熟練者は、よくある盤面であれば物凄い記憶力を保つが、ランダムに配置された盤面だと普通の人と同じ記憶力になる
これと似たような実験をプログラマーで行った場合、熟練プログラマーほど通常のプログラムに対しる記憶力が高くなったが、無意味なコードの場合は熟練者も初心者もたいして成績が変わらなかった。
1981年、ベル研究所のキャサリン・マッケイテンによる実験
デザインパターンはコードをチャンク化した例であり、その知識によって読みやすくなる、 ビーコンを残すと読みやすくなる
ビーコンとは、プログラマーがコードの内容を理解するのに役立つプログラムの部分のことを指します。
例えば、
「// 順次木探索を行う関数」というコメント
Node , Tree, leaf といった変数名
Chapter3. プログラミング言語の文法を素早く習得する方法
文法の知識は、コードを読む時に重要
書く時はその都度ググればいいかもしれないが、読む時は文法を知っていると知らないとで理解が異なる
フラッシュカードを使って文法を暗記しようと提案している
面倒だからやらないでいがちだが、地味に重要なので、新しい言語を習得する時は積極的にやっていこうkidooom.icon
間隔を空けて、復習を繰り返すこと
これは、様々な本や研究結果で言われている有効な記憶方法
一つずつ精緻化をしてスキーマを獲得していくことが大事
その都度ググっていたのでは精緻化は行われない
Chapter4. 複雑なコードの読み方
本書では、短期記憶とワーキングメモリは以下のように区別する
短期記憶:情報を保持する
ワーキングメモリ:情報を処理する
足し算を行うなど
どのような状態が読みやすいかは、人による
リファクタリングで読みやすくしたつもりが、他の人には読みにくくなっている逆リファクタリングも起こりうる
ただ、人間が共通して読みやすいコードというのも存在する
どうしても分からないコードは、印刷などして手書きメモを加えていくことも必要
依存関係を整理したり
関連する変数を線で繋げたり
処理の流れを自分で分かりやすいように書き込む
状態遷移表を書く
Chapter5. コードの深い理解に到達する
変数が使われているコードでは、上記の中のどの役割かを識別できると理解しやすくなる
ハンガリアン記法のような変数名付けにルールを設けるのは、上記のような役割を識別しやすくするため ブリガム・ヤング大学のジョナサン・シリト教授による、人間がコードを理解する際の段階分け p89
1. フォーカルポイントを見つける
フォーカルポイントとは、コード内に注目すべきポイント、とっかかりとなるポイント
Javaでいう main()メソッドや、エラーが発生した行、レビュー対象の行など
2. そのフォーカルポイントから知識を拡張していく
3. 関連している要素から、そのコードに利用されている概念を理解する
4. 複数の要素横断して利用されている概念を理解する
アルゴリズムやサブクラスなど
DIなどを使っていると、フォーカルポイントが見つけにくいのが悩み p90
依存性注入(DI: Dependency Injection)など、フレームワークやテクニックによっては、フォーカルポイントを断片化してバラバラに配置してしまうために、つながりが見えづらくなるケースがあります。 これはたまに感じるkidooom.icon
プログラマーの勤務時間の60%はプログラムの読む時間であるにもかかわらず、コードを読む練習をあまりしていない
プログラムを書く練習・勉強ばかりしていることは確かである
プログラムを読む能力は、文章読解力・自然言語処理能力に近い
コードを読む時に、本を読む時にようにどの行が重要な箇所なのか特定したり、要約をすることで理解が深まりやすい
Chapter6. プログラミングに関する問題をよりうまく解決するには
モデルを利用する
クラス図
状態遷移図
フローチャート
シーケンス図
描くことで頭が整理される
分かっていることを図にまとめておくことで、考えることにリソースを割ける
p113
メンタルモデルの定義として著者が最も好んでよく使うのは「メンタルモデルは、目の前の問題について推論するために、ワーキングメモリの中で概念を抽象化するものである」
ファイルシステムについて考えるとき、ファイルがフォルダに格納されている構造を頭に浮かぶ
実際のデータ上では、0と1の2進数であり、実際にはファイルやフォルダは存在しない
新しいドメインの仕事に取り掛かるときは、メンタルモデルの構築に意識を向けたほうが良さそうだ
ソースコードのメンタルモデル
データ構造
アーキテクチャパターン
ダイアグラム
モデリングツール
実際のコンピュータがどのように機能するかを抽象化したもの
Chapter7. 誤認識:思考に潜むバグ
2つ目のプログラミング言語を学ぶのは、最初の言語を学ぶよりも簡単
知識の転移が行われるから
しかし、誤解によるバグも生じやすい
静的型付け言語と動的型付け言語ではメンタルモデルが異なる
Chapter8. よりよい命名を行う方法
なぜ名前が重要なのか? p151
名前はコードの大部分を占める
コードレビューの4件に1件は命名に関する指摘
名前は最もアクセスしやすいドキュメント
名前はビーコンとして機能する
適した命名は、認知資源を節約させる